#include <QtConcurrentMap>
#include <QxtLogger>
#include <QSettings>
#include <QDateTime>
#include "Scene.hpp"
#include "Tester.hpp"
#include "Director.hpp"
//struct UpdateMap {
//    UpdateMap(float t_diff) :dTime(t_diff) { }
//    typedef void result_type;
//    void operator()(Actor* act) {
//        act->update(dTime);
//    }
//    float dTime;
//};

Director* Director::instance() {
    static Director obj;
    return &obj;
}
Director::Director(Actor *parent) : Actor(parent)
{
    qxtLog->info("Started the Director");
    currentScene = 0;
    set = new QSettings();
    if (!set->contains("general/configured")) generateConfig();
}

void Director::generateConfig() {
    set->setValue("window/x",100);
    set->setValue("window/y",100);
    set->setValue("window/width",640);
    set->setValue("window/height",480);
    set->setValue("gl/width",640);
    set->setValue("gl/height",480);
    set->setValue("general/configured",1);
    set->sync();
}
void Director::update(float f) {
    Q_UNUSED(f);

    //increment time
    counter = time.delta();

    //update it all concurrently -- once we know it works :S
    //QtConcurrent::blockingMap(cast,UpdateMap(time));

    if(!currentScene) {
        currentScene = new Scene("StartScene");
        currentScene->load();
        cast += currentScene->getActors();
        if(cast.empty()) {
            qxtLog->fatal() << "There are no actors to display in StartScene";
        }
    }
    //or not
    foreach(Actor *act, cast) {
        act->update( counter );
    }

    //render    
    action();
}

void Director::action() {
    // nada
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0, GETV("gl/width").toDouble()/GETV("gl/height").toDouble(), 1.5, 20.0);
    gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    foreach(Actor *act, cast) {
        act->action();
    }
    glFlush();
}

QVariant Director::getSetting( const QByteArray &key ) const {
    if( false ) {
        // this block for settings that aren't saved and exist per-state
    }
    else if( set->contains(key) ) return set->value(key);
    else return QVariant();
}
